<script lang="ts" setup>
import type { VbenFormSchema } from '@vben/common-ui';

import type { AuthModel } from '#/api';

import { computed, h, ref } from 'vue';

import { AuthenticationRegister, z } from '@vben/common-ui';
import { $t } from '@vben/locales';

import { registerByMobile, sendSmsCode } from '#/api';
import { MsgTemplateCodeEnum } from '#/enums/commonEnum';
import { useMessage } from '#/hooks/web/useMessage';

defineOptions({ name: 'Register' });

const CODE_LENGTH = 4;
const loading = ref(false);
const formRef = ref();

const formSchema = computed((): VbenFormSchema[] => {
  return [
    {
      component: 'VbenInput',
      componentProps: {
        placeholder: $t('authentication.mobileTip'),
      },
      fieldName: 'mobile',
      label: $t('authentication.mobile'),
      rules: z.string().min(1, { message: $t('authentication.mobileTip') }),
    },
    {
      component: 'VbenPinInput',
      componentProps: {
        codeLength: CODE_LENGTH,
        createText: (countdown: number) => {
          const text =
            countdown > 0
              ? $t('authentication.sendText', [countdown])
              : $t('authentication.sendCode');
          return text;
        },
        handleSendCode: async () => {
          try {
            const { valid } = await formRef.value
              .getFormApi()
              .validateField('mobile');

            if (!valid) {
              return false;
            }
            const values = await formRef.value.getFormApi().getValues();

            // templateCode 参数需要 提前在消息模板中配置
            await sendSmsCode(values.mobile, MsgTemplateCodeEnum.REGISTER_SMS);
            return true;
          } catch {
            return false;
          }
        },
        placeholder: $t('authentication.code'),
      },
      fieldName: 'code',
      label: $t('authentication.code'),
      rules: z.string().length(CODE_LENGTH, {
        message: $t('authentication.codeTip', [CODE_LENGTH]),
      }),
    },
    {
      component: 'VbenInputPassword',
      componentProps: {
        passwordStrength: true,
        placeholder: $t('authentication.password'),
      },
      fieldName: 'password',
      label: $t('authentication.password'),
      renderComponentContent() {
        return {
          strengthText: () => $t('authentication.passwordStrength'),
        };
      },
      rules: z.string().min(1, { message: $t('authentication.passwordTip') }),
    },
    {
      component: 'VbenInputPassword',
      componentProps: {
        placeholder: $t('authentication.confirmPassword'),
      },
      dependencies: {
        rules(values) {
          const { password } = values;
          return z
            .string({ required_error: $t('authentication.passwordTip') })
            .min(1, { message: $t('authentication.passwordTip') })
            .refine((value) => value === password, {
              message: $t('authentication.confirmPasswordTip'),
            });
        },
        triggerFields: ['password'],
      },
      fieldName: 'confirmPassword',
      label: $t('authentication.confirmPassword'),
    },
    {
      component: 'VbenCheckbox',
      fieldName: 'agreePolicy',
      renderComponentContent: () => ({
        default: () =>
          h('span', [
            $t('authentication.agree'),
            h(
              'a',
              {
                class: 'vben-link ml-1 ',
                href: '#',
              },
              `${$t('authentication.privacyPolicy')} & ${$t('authentication.terms')}`,
            ),
          ]),
      }),
      rules: z.boolean().refine((value) => !!value, {
        message: $t('authentication.agreeTip'),
      }),
    },
  ];
});
const { notification } = useMessage();
async function handleSubmit(data: AuthModel.RegisterByMobileVO) {
  try {
    data.key = MsgTemplateCodeEnum.REGISTER_SMS;
    const result = await registerByMobile(data);
    notification.success({
      message: '注册成功',
      description: `注册成功,请使用${result?.data}登录系统`,
      duration: 3,
    });
    formRef.value.goToLogin();
  } catch (error: any) {
    notification.error({
      message: '注册失败',
      description: error.msg ?? `注册失败`,
      duration: 3,
    });
  }
}
</script>

<template>
  <AuthenticationRegister
    ref="formRef"
    :form-schema="formSchema"
    :loading="loading"
    @submit="handleSubmit"
  />
</template>
